package com.example.demo.controller;

import com.example.demo.config.AjaxResult;
import com.example.demo.model.UserInfo;
import com.example.demo.model.UserInfo;
import com.example.demo.service.UserService;
import com.example.demo.service.FileService;
import com.example.demo.util.ConstVariable;
import com.example.demo.util.PasswordUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    
    @Autowired
    private FileService fileService;

    @PostMapping("/register")
    public AjaxResult register(@RequestBody UserInfo user, HttpSession session) {
        try {
            // 基本验证
            if (user.getUsername() == null || user.getUsername().trim().isEmpty()) {
                return AjaxResult.fail(-1, "用户名不能为空");
            }
            if (user.getPassword() == null || user.getPassword().trim().isEmpty()) {
                return AjaxResult.fail(-1, "密码不能为空");
            }
            if (user.getPhone() == null || user.getPhone().trim().isEmpty()) {
                return AjaxResult.fail(-1, "手机号不能为空");
            }

            // 先检查用户名是否已存在
            UserInfo existUser = userService.selectByUsername(user.getUsername());
            if (existUser != null) {
                return AjaxResult.fail(-1, "用户名已存在");
            }

            // 验证验证码
            String savedCaptcha = (String) session.getAttribute("code");
            if (savedCaptcha == null) {
                return AjaxResult.fail(-1, "验证码已过期，请重新获取");
            }
            if (!savedCaptcha.equalsIgnoreCase(user.getCaptcha())) {
                return AjaxResult.fail(-1, "验证码错误");
            }
            
            // 验证通过后删除session中的验证码
            session.removeAttribute("code");
            
            // 密码加密
            String encryptedPassword = PasswordUtil.encrypt(user.getPassword());
            
            if (userService.register(user.getUsername(), encryptedPassword, user.getPhone())) {
                return AjaxResult.success("注册成功", null);
            } else {
                return AjaxResult.fail(-1, "注册失败，请稍后重试");
            }
        } catch (Exception e) {
            log.error("注册失败", e);
            return AjaxResult.fail(-1, "注册失败：" + e.getMessage());
        }
    }

    @PostMapping("/login")
    public AjaxResult login(@RequestBody UserInfo user, HttpSession session) {
        try {
            log.info("接收到登录请求: {}", user.getUsername());

            // 基本验证
            if (StringUtils.isEmpty(user.getUsername()) || StringUtils.isEmpty(user.getPassword())) {
                return AjaxResult.fail("用户名和密码不能为空");
            }

            // 获取当前登录失败次数
            Integer attempts = (Integer) session.getAttribute("loginAttempts");
            attempts = attempts == null ? 0 : attempts;

            // 如果失败次数>=3，先验证验证码
            if (attempts >= 3) {
                String expectedCaptcha = (String) session.getAttribute("code");
                if (user.getCaptcha() == null || user.getCaptcha().trim().isEmpty()) {
                    return AjaxResult.fail("请输入验证码");
                }
                if (!user.getCaptcha().equalsIgnoreCase(expectedCaptcha)) {
                    return AjaxResult.fail("验证码错误");
                }
                // 验证码正确，继续处理
                session.removeAttribute("code");
            }

            // 验证用户名和密码
            UserInfo userInfo = userService.login(user.getUsername(), user.getPassword());
            
            if (userInfo == null) {
                attempts++;
                session.setAttribute("loginAttempts", attempts);
                
                if (attempts >= 3) {
                    return AjaxResult.fail("用户名或密码错误，请输入验证码");
                } else {
                    return AjaxResult.fail("用户名或密码错误");
                }
            }

            // 登录成功，清除失败次数
            session.removeAttribute("loginAttempts");
            
            log.info("登录成功，用户信息: id={}, username={}, nickname={}, avatar={}, phone={}, status={}", 
                userInfo.getId(),
                userInfo.getUsername(),
                userInfo.getNickname(),
                userInfo.getAvatar(),
                userInfo.getPhone(),
                userInfo.getStatus()
            );

            // 将用户信息存入session
            session.setAttribute(ConstVariable.USER_SESSION_KEY, userInfo);
            
            return AjaxResult.success("登录成功", userInfo);
            
        } catch (Exception e) {
            log.error("登录失败", e);
            return AjaxResult.fail("登录失败：" + e.getMessage());
        }
    }

    @RequestMapping("/get-user")
    public AjaxResult getUser(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session == null) {
            return AjaxResult.fail(401, "当前用户未登录");
        }
        UserInfo userInfo = (UserInfo) session.getAttribute(ConstVariable.USER_SESSION_KEY);
        if (userInfo == null) {
            return AjaxResult.fail(401, "当前用户未登录");
        }
        log.info("Session中的用户信息: id={}, username={}, nickname={}, avatar={}, phone={}, status={}, createTime={}, updateTime={}", 
            userInfo.getId(),
            userInfo.getUsername(),
            userInfo.getNickname(),
            userInfo.getAvatar(),
            userInfo.getPhone(),
            userInfo.getStatus(),
            userInfo.getCreateTime(),
            userInfo.getUpdateTime()
        );
        return AjaxResult.success("获取用户信息成功", userInfo);
    }

    @RequestMapping("/logout")
    public AjaxResult logout(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute(ConstVariable.USER_SESSION_KEY) == null) {
            return AjaxResult.fail(401, "当前用户未登录");
        }
        session.removeAttribute(ConstVariable.USER_SESSION_KEY);
        return AjaxResult.success("退出成功", null);
    }

    @PostMapping("/change-password")
    public AjaxResult changePassword(@RequestParam("currentPassword") String currentPassword,
                                   @RequestParam("newPassword") String newPassword,
                                   HttpSession session) {
        // 从 session 获取当前用户信息
        UserInfo userInfo = (UserInfo) session.getAttribute(ConstVariable.USER_SESSION_KEY);
        if (userInfo == null) {
            return AjaxResult.fail(401, "用户未登录");
        }

        // 先验证旧密码是否正确
        UserInfo user = userService.selectByUsername(userInfo.getUsername());
        if (user == null) {
            return AjaxResult.fail(400, "用户不存在");
        }

        // 验证旧密码
        if (!PasswordUtil.decrypt(currentPassword, user.getPassword())) {
            return AjaxResult.fail(400, "旧密码错误");
        }

        // 对新密码进行加密
        String encryptedPassword = PasswordUtil.encrypt(newPassword);
        
        // 更新密码
        int result = userService.changePassword(encryptedPassword, userInfo.getId());
        if (result <= 0) {
            return AjaxResult.fail(500, "修改密码失败，请稍后再试");
        }

        // 清除 session，让用户重新登录
        session.invalidate();
        
        return AjaxResult.success("密码修改成功", null);
    }

    /**
     * 获取用户详细信息
     */
    @GetMapping("/detail")
    public AjaxResult getUserDetail(HttpSession session) {
        UserInfo userInfo = (UserInfo) session.getAttribute(ConstVariable.USER_SESSION_KEY);
        if (userInfo == null) {
            return AjaxResult.fail(401, "用户未登录");
        }
        
        UserInfo userDetail = userService.getUserDetail(userInfo.getId());
        return AjaxResult.success(userDetail);
    }

    @PostMapping("/update-info")
    public AjaxResult updateUserInfo(
            @RequestParam(required = false) MultipartFile avatar,
            @RequestParam(required = false) String nickname,
            @RequestParam(required = false) String phone,
            HttpSession session) {
        
        try {
            log.info("1. 开始处理更新请求");
            log.info("收到更新请求: nickname={}, phone={}, avatar={}", nickname, phone, avatar != null ? "有文件" : "无文件");
            
            UserInfo userInfo = (UserInfo) session.getAttribute(ConstVariable.USER_SESSION_KEY);
            log.info("2. 从session获取用户信息: {}", userInfo);
            
            if (userInfo == null) {
                return AjaxResult.fail(401, "用户未登录");
            }

            try {
                log.info("3. 开始创建updateInfo对象");
                UserInfo updateInfo = new UserInfo();
                updateInfo.setId(userInfo.getId());
                log.info("4. 设置ID: {}", userInfo.getId());
                if (nickname != null && !nickname.trim().isEmpty()) {
                    updateInfo.setNickname(nickname);
                    log.info("5. 设置昵称: {}", nickname);
                }
                updateInfo.setPhone(phone);
                log.info("6. 设置电话: {}", phone);

                // 如果上传了新头像
                if (avatar != null && !avatar.isEmpty()) {
                    log.info("8. 开始处理头像上传");
                    AjaxResult uploadResult = fileService.uploadImage(avatar);
                    if (uploadResult.getState() == 1) {
                        String avatarUrl = (String) uploadResult.getData();
                        log.info("获取到新的头像URL: {}", avatarUrl);
                        updateInfo.setAvatar(avatarUrl);
                        log.info("9. 设置头像URL: {}", avatarUrl);
                    } else {
                        return AjaxResult.fail("头像上传失败：" + uploadResult.getMsg());
                    }
                }

                log.info("10. 准备执行数据库更新，updateInfo: {}", updateInfo);

                // 更新数据库
                int rows = userService.updateUserInfo(updateInfo);
                log.info("11. 数据库更新结果: {}", rows);

                if (rows > 0) {
                    // 更新成功后，更新session中的用户信息
                    if (nickname != null && !nickname.trim().isEmpty()) {
                        userInfo.setNickname(nickname);
                    }
                    userInfo.setPhone(phone);
                    if (updateInfo.getAvatar() != null) {
                        userInfo.setAvatar(updateInfo.getAvatar());
                    }
                    session.setAttribute(ConstVariable.USER_SESSION_KEY, userInfo);
                    log.info("12. 更新session成功");
                    return AjaxResult.success("更新成功");
                } else {
                    return AjaxResult.fail("更新失败");
                }
            } catch (Exception e) {
                log.error("内部处理异常", e);
                throw e;
            }
        } catch (Exception e) {
            log.error("更新用户信息失败", e);
            return AjaxResult.fail("更新失败：" + e.getMessage());
        }
    }

    @PostMapping("/update-reputation")
    public AjaxResult updateReputation(@RequestParam Integer userId, @RequestParam Integer rating) {
        try {
            if (userId == null || rating == null) {
                return AjaxResult.fail("参数不能为空");
            }
            
            // 根据评分计算信誉分变化
            double reputationChange;
            switch (rating) {
                case 5:
                    reputationChange = 0.1;
                    break;
                case 4:
                    reputationChange = 0.05;
                    break;
                case 3:
                    reputationChange = 0.0;
                    break;
                case 2:
                    reputationChange = -0.05;
                    break;
                case 1:
                    reputationChange = -0.1;
                    break;
                default:
                    return AjaxResult.fail("无效的评分");
            }
            
            // 更新用户信誉分
            boolean success = userService.updateUserReputation(userId, reputationChange);
            
            if (success) {
                return AjaxResult.success("信誉分更新成功");
            } else {
                return AjaxResult.fail("信誉分更新失败");
            }
        } catch (Exception e) {
            log.error("更新信誉分失败", e);
            return AjaxResult.fail("更新信誉分失败：" + e.getMessage());
        }
    }
}
